package org.robot;

import java.io.File;

import org.robot.component.Attachment;
import org.robot.component.Page;
import org.robot.component.Regulation;
import org.robot.component.Rule;
import org.robot.config.Config;
import org.robot.power.Engine;
import org.robot.power.Schedule;
import org.robot.utils.FileUtil;

public abstract class Spider {

    private Schedule schedule = new Schedule();
    private Regulation regulation = new Regulation();
    private Config config = new Config();
    private Engine engine;
    private Long taskid;

    public Spider() {}

	public Spider(Long taskid) {
		this.taskid = taskid;
	}

	/**
     * 可以添加多个seed
     * @param seed 初始链接
     */
    public void addSeed(String seed) {
    	addSeed(seed, "seed");
    }
    
    public void addSeed(String seed, String type) {
    	schedule.add(new Attachment(seed, type).setSeed(true));
    }

    public void addRegex(String regex, String type) {
        regulation.add(Rule.createRegexRule(regex).setType(type));
    }

    public void addSelector(String selector, String type) {
        regulation.add(Rule.createSelectorRule(selector).setType(type));
    }

    public void addRule(String selector, String regex, String type) {
        regulation.add(Rule.createRule(selector, regex).setType(type));
    }

    /**
     * 添加链接规则
     * @param selector 选择器，具体到要解析的元素，一般是a标签
     * @param regex 链接满足的正则规则
     * @param attr 要获取的标签的属性，和selector是对应的，一般是href
     * @param type 这类链接的类型，到时会以改类型为文件夹的名字把网页存到本地
     */
    public void addRule(String selector, String regex, String attr, String type) {
        regulation.add(Rule.createCompleteRule(selector, regex, attr).setType(type));
    }
    
    /**
     * 只能应用于paper
     * @author pdz
     * @date 2019年2月19日
     * @param selector
     * @param regex
     */
    public void addPdfRule(String selector, String regex) {
    	regulation.add(Rule.createRule(selector, regex).setType("_pdf_"));
    }
    
    /**
     * 只能应用于paper
     * @author pdz
     * @date 2019年2月19日
     * @param selector
     */
    public void addPdfSelectorRule(String selector) {
    	addPdfRule(selector, ".+");
    }
    
    /**
     * 只能应用于paper
     * @author pdz
     * @date 2019年2月19日
     * @param regex
     */
    public void addPdfRegexRule(String regex) {
    	addPdfRule("a[href]", regex);
    }

    public abstract void parse(Page page) throws Exception;

    public void start() {
        // 检查baseDirectory
        if (config.getBaseDirectory() == null)
            throw new RuntimeException("baseDirectory不能为null");
        engine = new Engine(this);
        engine.start();
    }

    //设置存储父文件夹
    public void setBaseDirectory(String baseDirectory) {
    	config.setBaseDirectory(baseDirectory + "/" + getClass().getSimpleName());
    }
    
    /**
     * 如果需要自定义文件名，可以重写该方法
     * @param url
     * @param type
     * @param baseDirectory
     * @return
     */
    public File destFile(String url, String type, String baseDirectory) {
    	return FileUtil.destFile(url, type, baseDirectory);
    }

    /**
     * 使用重载的带参数的方法
     * 设置手动添加的标记
     */
    @Deprecated
    public void addByHand() {
        regulation.add(new Rule());
    }
    
    /**
     * 设置手动添加的标记
     */
    public void addByHand(String type) {
    	regulation.add(new Rule(type));
    }
    
	public Schedule getSchedule() {
		return schedule;
	}

	public Spider setSchedule(Schedule schedule) {
		this.schedule = schedule;
		return this;
	}

	public Regulation getRegulation() {
		return regulation;
	}

	public Spider setRegulation(Regulation regulation) {
		this.regulation = regulation;
		return this;
	}

	public Config getConfig() {
		return config;
	}

	public Spider setConfig(Config config) {
		this.config = config;
		return this;
	}

	public Long getTaskid() {
		return taskid;
	}

	public Spider setTaskid(Long taskid) {
		this.taskid = taskid;
		return this;
	}


}
